#pragma once

#include <vector>
#include <memory>
#include <mutex>
#include <unordered_set>
#include <unordered_map>
#include <type_traits>
#include <iostream>
#include <iomanip>

namespace viml {

/**
 * 简化的对象池基类
 */
class SimpleObjectPoolBase {
public:
    // 对象池统计信息
    struct SimplePoolStats {
        size_t total_allocated = 0;
        size_t total_reclaimed = 0;
        size_t current_in_use = 0;
        size_t pool_size = 0;
        size_t peak_usage = 0;
        double hit_rate = 0.0;
        size_t allocation_calls = 0;
        size_t pool_hits = 0;
    };
public:
    virtual ~SimpleObjectPoolBase() = default;
    virtual size_t get_allocated_count() const = 0;
    virtual size_t get_pool_size() const = 0;
    virtual void clear() = 0;
    virtual void shrink_to_fit() = 0;
    virtual SimplePoolStats get_stats() const = 0;
};

/**
 * 简化对象池
 * 基本的池化分配和回收
 */
template<typename T>
class SimpleObjectPool : public SimpleObjectPoolBase {

private:
    // 简单的对象存储
    struct SimpleNode {
        alignas(T) unsigned char storage[sizeof(T)];
        bool in_use = false;
        size_t index = 0;
    };

    // 池管理
    std::vector<std::unique_ptr<SimpleNode>> pool_;
    std::vector<T*> free_list_;
    mutable std::mutex pool_mutex_;

    // 统计信息
    mutable SimplePoolStats stats_;
    static constexpr size_t INITIAL_POOL_SIZE = 64;
    static constexpr size_t MAX_POOL_SIZE = 256;

public:
    SimpleObjectPool() {
        pool_.reserve(INITIAL_POOL_SIZE);
        free_list_.reserve(INITIAL_POOL_SIZE);

        for (size_t i = 0; i < INITIAL_POOL_SIZE; ++i) {
            auto node = std::make_unique<SimpleNode>();
            free_list_.push_back(reinterpret_cast<T*>(node->storage));
            node->index = i;
            pool_.push_back(std::move(node));
        }

        stats_.pool_size = INITIAL_POOL_SIZE;
    }

    ~SimpleObjectPool() {
        clear();
    }

    // 获取对象
    std::unique_ptr<T> acquire() {
        std::lock_guard<std::mutex> lock(pool_mutex_);

        ++stats_.allocation_calls;
        stats_.current_in_use++;
        stats_.peak_usage = std::max(stats_.peak_usage, stats_.current_in_use);

        // 尝试从池中获取
        if (!free_list_.empty()) {
            auto* raw_ptr = free_list_.back();
            free_list_.pop_back();

            // 找到对应的节点
            for (auto& node : pool_) {
                if (reinterpret_cast<T*>(node->storage) == raw_ptr) {
                    node->in_use = true;
                    break;
                }
            }

            ++stats_.pool_hits;
            ++stats_.total_allocated;

            // 使用自定义删除器来安全释放
            return std::unique_ptr<T>(raw_ptr, [this](T* ptr) {
                this->release(ptr);
            });
        }

        // 池中没有可用对象，分配新的
        auto obj = std::make_unique<T>();
        ++stats_.total_allocated;

        return obj;
    }

    // 释放对象
    void release(T* obj) {
        if (!obj) return;

        std::lock_guard<std::mutex> lock(pool_mutex_);

        --stats_.current_in_use;
        ++stats_.total_reclaimed;

        // 尝试将对象放回池中（简化处理）
        bool is_from_pool = false;
        for (const auto& node : pool_) {
            if (reinterpret_cast<T*>(node->storage) == obj) {
                is_from_pool = true;
                node->in_use = false;

                // 检查是否已在free_list中
                bool already_in_list = false;
                for (T* existing : free_list_) {
                    if (existing == obj) {
                        already_in_list = true;
                        break;
                    }
                }

                if (!already_in_list) {
                    free_list_.push_back(obj);
                }
                break;
            }
        }

        // 计算命中率
        if (stats_.allocation_calls > 0) {
            stats_.hit_rate = static_cast<double>(stats_.pool_hits) / stats_.allocation_calls;
        }
    }

    // 获取统计信息
    SimplePoolStats get_stats() const {
        std::lock_guard<std::mutex> lock(pool_mutex_);
        return stats_;
    }

    // 基类接口实现
    size_t get_allocated_count() const override {
        return get_stats().total_allocated;
    }

    size_t get_pool_size() const override {
        return get_stats().pool_size;
    }

    void clear() override {
        std::lock_guard<std::mutex> lock(pool_mutex_);
        pool_.clear();
        free_list_.clear();
        stats_ = SimplePoolStats{};
        stats_.pool_size = 0;
    }

    void shrink_to_fit() override {
        std::lock_guard<std::mutex> lock(pool_mutex_);

        // 移除未使用的节点
        size_t removed = 0;
        auto it = pool_.begin();
        while (it != pool_.end()) {
            if (!(*it)->in_use) {
                it = pool_.erase(it);
                ++removed;
            } else {
                ++it;
            }
        }

        stats_.pool_size = pool_.size();
    }

    // 预热对象池
    void warm_up(size_t count) {
        std::lock_guard<std::mutex> lock(pool_mutex_);

        for (size_t i = 0; i < count && pool_.size() < MAX_POOL_SIZE; ++i) {
            auto node = std::make_unique<SimpleNode>();
            node->index = i;
            pool_.push_back(std::move(node));

            auto* obj = reinterpret_cast<T*>(node->storage);
            free_list_.push_back(obj);
        }

        stats_.pool_size = pool_.size();
    }
};

/**
 * 简化的对象池管理器
 */
class SimpleObjectPoolManager {
private:
    enum class PoolType {
        STRING_POOL,
        LIST_POOL,
        DICT_POOL,
        FUNCTION_POOL,
        OTHER_POOL
    };

    std::unordered_map<PoolType, std::unique_ptr<SimpleObjectPoolBase>> pools_;
    mutable std::mutex manager_mutex_;

    struct ManagerStats {
        size_t total_pools = 0;
        size_t total_allocated = 0;
        size_t total_in_use = 0;
        double overall_hit_rate = 0.0;
    } manager_stats_;

public:
    SimpleObjectPoolManager() = default;
    ~SimpleObjectPoolManager() = default;

    // 注册对象池
    template<typename T>
    void register_pool(PoolType type) {
        std::lock_guard<std::mutex> lock(manager_mutex_);

        auto pool = std::make_unique<SimpleObjectPool<T>>();
        pools_[type] = std::move(pool);
        manager_stats_.total_pools++;
    }

    // 获取对象池
    template<typename T>
    SimpleObjectPool<T>* get_pool(PoolType type) {
        std::lock_guard<std::mutex> lock(manager_mutex_);

        auto it = pools_.find(type);
        if (it != pools_.end()) {
            return static_cast<SimpleObjectPool<T>*>(it->second.get());
        }
        return nullptr;
    }

    // 获取统计信息
    struct PoolReport {
        PoolType type;
        size_t total_allocated = 0;
        size_t current_in_use = 0;
        size_t pool_size = 0;
        double hit_rate = 0.0;
    };

    std::vector<PoolReport> get_pool_reports() const {
        std::lock_guard<std::mutex> lock(manager_mutex_);

        std::vector<PoolReport> reports;
        for (const auto& pair : pools_) {
            PoolReport report;
            report.type = static_cast<PoolType>(pair.first);

            // 获取基本统计信息
            auto& pool = pair.second;
            auto base_stats = pool->get_stats();

            report.total_allocated = base_stats.total_allocated;
            report.current_in_use = base_stats.current_in_use;
            report.pool_size = base_stats.pool_size;
            report.hit_rate = base_stats.hit_rate;

            reports.push_back(report);
        }

        return reports;
    }

    ManagerStats get_manager_stats() const {
        std::lock_guard<std::mutex> lock(manager_mutex_);
        return manager_stats_;
    }

    // 清理所有对象池
    void clear_all_pools() {
        std::lock_guard<std::mutex> lock(manager_mutex_);

        for (auto& pair : pools_) {
            pair.second->clear();
        }

        manager_stats_ = ManagerStats{};
        manager_stats_.total_pools = pools_.size();
    }

    // 优化所有对象池
    void optimize_all_pools() {
        std::lock_guard<std::mutex> lock(manager_mutex_);

        for (auto& pair : pools_) {
            pair.second->shrink_to_fit();
        }
    }

    // 打印统计信息
    void print_stats() const {
        std::lock_guard<std::mutex> lock(manager_mutex_);

        std::cout << "=== 简化对象池管理器统计 ===" << std::endl;
        std::cout << "管理的对象池数量: " << manager_stats_.total_pools << std::endl;
        std::cout << "总分配对象数: " << manager_stats_.total_allocated << std::endl;
        std::cout << "当前使用对象数: " << manager_stats_.total_in_use << std::endl;
        std::cout << "总体命中率: " << std::fixed << std::setprecision(2)
                  << (manager_stats_.overall_hit_rate * 100) << "%" << std::endl;

        std::cout << "\n各对象池详细统计:" << std::endl;
        auto reports = get_pool_reports();
        for (const auto& report : reports) {
            const char* type_names[] = {"字符串池", "列表池", "字典池", "函数池", "其他池"};
            int type_idx = static_cast<int>(report.type);

            std::cout << type_names[type_idx] << ":" << std::endl;
            std::cout << "  池大小: " << report.pool_size << std::endl;
            std::cout << "  总分配: " << report.total_allocated << std::endl;
            std::cout << "  当前使用: " << report.current_in_use << std::endl;
            std::cout << "  命中率: " << std::fixed << std::setprecision(2)
                      << (report.hit_rate * 100) << "%" << std::endl;
        }
        std::cout << "=================" << std::endl;
    }
};

/**
 * 全局对象池管理器
 */
class GlobalSimpleObjectPool {
private:
    static std::unique_ptr<SimpleObjectPoolManager> instance_;
    static std::mutex instance_mutex_;
    static bool initialized_;

public:
    static SimpleObjectPoolManager& get_instance();
    static void initialize();
    static void shutdown();
    static bool is_initialized();
};

} // namespace viml